package gui.typeEditors;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JColorChooser;

import owg.util.Calc;

public class ColorEditor extends TypeEditor<float[]> implements ActionListener
	{
	static final long serialVersionUID = 2704835030524222876L;
	
	FloatEditor[] fields;
	
	JButton button;
	float[] value;
	boolean ignoreEvents = false;
	Color origcolor;
	
	/**
	 * 
	 * @param initialValue The initial value, a float array with at least 4 elements. The array will not be modified,
	 * but the reference may be reused.
	 */
	public ColorEditor(float[] initialValue)
		{
		super();
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		
		fields = new FloatEditor[4];
		for(int i=0; i<4; i++)
			{
			fields[i] = new FloatEditor(initialValue[i], 1.0f, DoubleEditor.DEFAULT_COLUMNS/4, true);
			fields[i].setMinimumSize(fields[i].getPreferredSize());
			final int index = i;
			fields[i].addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e)
					{
					float[] newVal = value.clone();
					newVal[index] = (float)Calc.limit(fields[index].getValue(),0,1);
					setValue(newVal,true);
					}});
			add(fields[i]);
			}
		
		button = new JButton("N/A");
		add(button);
		button.addActionListener(this);
		
		setValue(initialValue, false);
		this.setToolTipTextToSubComponents("Edit this colour.");
		}

	private void setValue(float[] val, boolean fire)
		{
		float[] pVal = value;
		value = val;
		ignoreEvents = true;
		button.setBackground(asColor(value, false));
		button.setForeground(((val[0]+(val[1]+val[2])>1.5f)?Color.BLACK:Color.WHITE));
		button.setText(Integer.toHexString(button.getBackground().getRGB()));
		ignoreEvents = false;
		for(int i=0; i<4; i++)
			{
			fields[i].setValue(value[i]);
			}
		if(fire && ((pVal==null && value!=null) || !pVal.equals(value)))
			{
			fireActionEvents();
			flash(Color.GREEN);
			}
		}

	@Override
	public void actionPerformed(ActionEvent e)
		{
		if(!ignoreEvents)
			parseValue();
		}

	private void parseValue()
		{
		try
			{
			setValue(asFloat(JColorChooser.showDialog(null, "COHOOSE YUOR CLOOR", asColor(value, true))), true);
			}
		catch (IllegalArgumentException e)
			{
			setValue(value, false);
			}
		}

	synchronized void color(Color color)
		{
		button.setBackground(color);
		}

	private void flash(Color color)
		{
		color(color);
		flashThread(new Runnable(){public void run(){color(asColor(value, false));}}, 33);
		}

	protected Color asColor(float[] value, boolean includeAlpha)
		{
		Calc.limit(value, 0f, 1f);
		return new Color(value[0], value[1], value[2], includeAlpha?value[3]:1.0f);
		}
	private float[] asFloat(Color c) throws IllegalArgumentException
		{
		if(c == null)
			throw new IllegalArgumentException("Null color not allowed");
		return new float[] {c.getRed()/255f,c.getGreen()/255f,c.getBlue()/255f,c.getAlpha()/255f};
		}

	@Override
	public float[] getValue()
		{
		return value;
		}
	
	@Override
	public void setValue(float[] val)
		{
		setValue(val, false);
		}
	
	@Override
	public String getValueString()
		{
		return value[0]+","+value[1]+","+value[2]+","+value[3];
		}
	
	@Override
	public void setToolTipTextToSubComponents(String text)
		{
		button.setToolTipText(text);
		String[] extendedTips = {"red","green","blue","alpha"};
		for(int i=0; i<4; i++)
			{
			String fieldTip = text;
			String fieldTipEnd = "Define the "+extendedTips[i]+" value here.";
			int endIndex = fieldTip.lastIndexOf("</body>");
			if(endIndex != -1)
				fieldTip = fieldTip.substring(0,endIndex)+"<br/>"+fieldTipEnd+"</body></html>";
			else
				fieldTip += " "+fieldTipEnd;
				
			fields[i].setToolTipText(fieldTip);
			}
		}

	@Override
	public void setSubComponentsEnabled(boolean en)
		{
		button.setEnabled(en);
		for(int i=0; i<3; i++)
			{
			fields[i].setEnabled(en);
			}
		}
	}
